#include "tokenizer.h"

inline bool Tokenizer::next(){
   int ret=1;
   if (!hascur) ret=fscanf(f," %s",cur);
   hascur=ret>0;
   return hascur;
}
inline void Tokenizer::check(){
   hascur=(bool) strlen(cur);
}
inline int Tokenizer::substr(char const* str1,char const* str2){
   int i=0;
   while (1){
      if (str1[i]==0) return true;
      if (str2[i]==0) return false;
      if (str1[i]==str2[i]) {
         i++;
      } else {
         return false;
      }
   }
}
inline bool Tokenizer::eqstr(char const* str1,char const* str2){
   int i=0;
   while (1){
      if (str1[i]==0 && str2[i]==0) return true;
      if (str1[i]==0) return false;
      if (str2[i]==0) return false;
      if (str1[i]==str2[i]) {
         i++;
      } else {
         return false;
      }
   }
}
inline void Tokenizer::movestr(int mv){
   int i=mv,n=0;
   while (1){
      cur[n]=cur[i];
      if (cur[i]==0) break;
      i++;
      n++;
   }
}
bool Tokenizer::matchstart(char const* fm){
   if (!next()) return false;
   int pos=substr(fm,cur);
   if (pos){
      movestr(pos);
      check();
      return true;
   } else {
      return false;
   }
}
bool Tokenizer::match(char const* fm){
   if (!next()) return false;
   if (eqstr(fm,cur)){
      hascur=false;
      return true;
   } else {
      return false;
   }
}
bool Tokenizer::get(char* buf){
   if (!next()) return false;
   strcpy(buf,cur);
   hascur=false;
   return true;
}
bool Tokenizer::get(int* buf){
   if (!next()) return false;
   int ret=sscanf(cur,"%d",buf);
   check();
   return (ret>0);
}
bool Tokenizer::scan(char const* fm,int* buf){
   char fm2[100]="";
   char remainder[255];
   if (!next()) return false;
   strcat(fm2,fm);
   strcat(fm2,"%s");
   int ret=sscanf(cur,fm2,buf,remainder); // sscanf does not modify cur WARNING undocumented
   if (ret<1) return false;
   if (ret>1){
      strcpy(cur,remainder);
   } else {
      hascur=false;
   }
   return true;
}
bool Tokenizer::scan(char const* fm,char* buf){
   char fm2[100]="";
   char remainder[255];
   if (!next()) return false;
   strcat(fm2,fm);
   strcat(fm2,"%s");
   int ret=sscanf(cur,fm2,buf,remainder); // sscanf does not modify cur WARNING undocumented
   if (ret<1) return false;
   if (ret>1){
      strcpy(cur,remainder);
   } else {
      hascur=false;
   }
   return true;
}
void Tokenizer::skipline(){
   hascur=false;
   fscanf(f,"%*[^\n]");
}